﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Kgb.Model.Models;
using Kgb.Service.Repository.Interface;
using System.Runtime.Caching;

namespace Kgb.Service.Repository
{
    public class PlayerRepository : IPlayerRepository
    {
        private List<Player> _players;
        private int _nextId;

        public PlayerRepository()
        {
            if (MemoryCache.Default["players"] == null)
            {
                _players = new List<Player>();
                MemoryCache.Default.Add(new CacheItem("players", _players), new CacheItemPolicy() { AbsoluteExpiration = new DateTime(9999, 12, 31) });
            }
            else
            {
                _players = (List<Player>)MemoryCache.Default["players"];
            }

            if (_players.Any())
            {
                _nextId = _players.Max(c => c.Id) + 1;
            }
            else
            {
                _nextId = 1;
            }
        }

        public IQueryable<Player> GetAll()
        {
            return _players.AsQueryable();
        }

        public IQueryable<Player> GetAllByRoom(int roomId)
        {
            return _players.Where(p => p.RoomId == roomId).AsQueryable();
        }

        public IQueryable<Player> GetAllByLobby(int lobbyId)
        {
            return _players.Where(p => p.LobbyId == lobbyId).AsQueryable();
        }

        public Player Get(int id)
        {
            return _players.Find(c => c.Id == id);
        }

        public Player Add(Player player)
        {
            if (string.IsNullOrEmpty(player.Name))
                throw new ArgumentException("The player must have a name!","Name");

            if (string.IsNullOrEmpty(player.Session()))
                throw new ArgumentException("The player must have a session id!", "SessionId");

            if (_players.Where(p => p.Name == player.Name).Any())
                throw new Exception(string.Format("Alread exists a player with name: {0}!", player.Name)); 
            
            if (_players.Where(p => p.Session() == player.Session()).Any())
                throw new Exception("Alread exists a player with this session id!");
            
            player.Id = _nextId++;
            _players.Add(player);
            return player;
        }

        public void Remove(int id)
        {
            Player player = _players.Find(c => c.Id == id);
            if (player != null)
            {
                LocationRepository l = new LocationRepository();
                var locPlayer = l.GetByPlayer(player);

                if (locPlayer != null)
                {
                    locPlayer.State = "livre";
                    locPlayer.LocationPlayer = null;
                }

                _players.Remove(player);
            }
        }

        public bool Update(Player player)
        {
            int index = _players.FindIndex(c => c.Id == player.Id);
            if (index == -1)
            {
                return false;
            }
            player.SessionId = _players[index].Session();
            _players.RemoveAt(index);
            _players.Add(player);   
            return true;
        }
    }
}